import clsx from 'clsx'
import { useRequest } from 'ahooks'
import { Icon } from '@taroify/icons'
import { filter, isEmpty, sumBy } from 'lodash'
import { ScrollView, Text, View } from '@tarojs/components'
import { Cell, Empty, Loading, Navbar, Popup, SafeArea } from '@taroify/core'
import { type FC, type ReactNode, useEffect, useMemo, useState } from 'react'

import { getDates } from '@/apis/order'
import styles from './styles.module.scss'
import { useSystemInfo } from '@/hooks/useSystemInfo'

export interface TimeSelectProps {
  open?: boolean
  title?: ReactNode
  emptyText?: ReactNode
  cancelText?: ReactNode
  confirmText?: ReactNode
  onClose?: () => void
  onConfirm?: (value: string[], item: Data) => void
}

const formatDate = (date: string) => {
  const [, month, day] = date.split('-')
  return `${Number(month)}.${Number(day)}`
}

const filterTimes = (items?: Data[], isAm?: boolean) => {
  if (isEmpty(items)) return []

  return filter(items, (item) => {
    return isAm ? Number(item.timeEnd.slice(0, 2)) <= 12 : Number(item.timeStart.slice(0, 2)) > 12
  })
}

const reduceData = (items: Data[] = []) => {
  return items.reduce((acc: Data[], item) => {
    const ams = filterTimes(item.carServiceTimeUnitVoList, true)
    const pms = filterTimes(item.carServiceTimeUnitVoList, false)

    return [
      ...acc,
      {
        ...item,
        type: 'am',
        times: ams,
        disabled: sumBy(ams, 'availableSize') === 0,
      },
      {
        ...item,
        type: 'pm',
        times: pms,
        disabled: sumBy(pms, 'availableSize') === 0,
      },
    ]
  }, []) as Data[]
}

export const TimeSelect: FC<TimeSelectProps> = ({
  open,
  title = '选择服务时间',
  emptyText = '暂无可预约时间',
  cancelText = '取消',
  confirmText = '确定',
  onClose,
  onConfirm,
}) => {
  const [tab, setTab] = useState(0)
  const { windowWidth } = useSystemInfo()
  const [scrollLeft, setScrollLeft] = useState(0)

  const { data, loading, run } = useRequest(getDates, { manual: true })
  const list = useMemo(() => reduceData(data), [data])
  const times = useMemo<Data[]>(() => list?.[tab]?.times ?? [], [list, tab])

  useEffect(() => {
    open && run()
  }, [open])

  const handleTab = (idx: number) => {
    setTab(idx)
    setScrollLeft(76 * idx + 38 - windowWidth / 2)
  }

  const handleConfirm = (item: Data) => {
    if (item.availableSize === '0') return

    onConfirm?.([item.dayStart, item.dayEnd], item)
    onClose?.()
  }

  return (
    <Popup className={styles.popup} open={open} placement="bottom" onClose={onClose}>
      <Navbar bordered>
        <Navbar.NavLeft icon={false} onClick={onClose}>
          {cancelText}
        </Navbar.NavLeft>
        <Navbar.Title>{title}</Navbar.Title>
        <Navbar.NavRight onClick={handleConfirm}>{confirmText}</Navbar.NavRight>
      </Navbar>
      <SafeArea className="relative" position="bottom">
        {isEmpty(list) ? (
          loading ? (
            <View className="p-6 flex flex-center" style="min-height:368px">
              <Loading direction="vertical">
                <Text>加载中...</Text>
              </Loading>
            </View>
          ) : (
            <Empty style="min-height:368px">
              <Empty.Image />
              <Empty.Description>{emptyText}</Empty.Description>
            </Empty>
          )
        ) : (
          <>
            <ScrollView
              className="mb-2 flex day-scroll-view"
              enableFlex
              scrollX
              scrollWithAnimation
              scrollLeft={scrollLeft}
              style="height:88px"
            >
              {list?.map((item, idx) => (
                <View
                  className={clsx(styles.tab, tab === idx && styles.active)}
                  key={idx}
                  style="width:76px"
                  onClick={() => handleTab(idx)}
                >
                  <Text className="text-xs">{item.week}</Text>
                  <Text className="text-sm">{formatDate(item.day)}</Text>
                  <View className="flex flex-center" style="min-height:32px">
                    <Icon classPrefix="icon" name={item.type === 'am' ? 'shangwu' : 'xiawu'} size={32} />
                  </View>
                </View>
              ))}
            </ScrollView>
            <ScrollView className="flex time-scroll-view" scrollY style="height:264px">
              {isEmpty(times) ? (
                <Empty style="min-height:264px">
                  <Empty.Image />
                  <Empty.Description>{emptyText}</Empty.Description>
                </Empty>
              ) : (
                times.map((item, idx) => (
                  <Cell key={idx} isLink title={item.timeInterval} onClick={() => handleConfirm(item)}>
                    {item.availableSize > 0 ? (
                      <Text className="text-xs text-default">剩余 {item.availableSize}</Text>
                    ) : (
                      <Text className="text-xs">已满</Text>
                    )}
                  </Cell>
                ))
              )}
            </ScrollView>
          </>
        )}
      </SafeArea>
    </Popup>
  )
}

export default TimeSelect
